/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.qsdm.es.dao;

import com.qsdm.es.dao.exceptions.IllegalOrphanException;
import com.qsdm.es.dao.exceptions.NonexistentEntityException;
import com.qsdm.es.dao.exceptions.PreexistingEntityException;
import com.qsdm.es.persistence.*;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author alberto
 */
public class CursoJpaController extends BasicJpaController {

    public void create(Curso curso) throws PreexistingEntityException, Exception {
        if (curso.getCalendariocursoList() == null) {
            curso.setCalendariocursoList(new ArrayList<Calendariocurso>());
        }
        if (curso.getHorariocursoList() == null) {
            curso.setHorariocursoList(new ArrayList<Horariocurso>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Centroformacion centroFormacion = curso.getCentroFormacion();
            if (centroFormacion != null) {
                centroFormacion = em.getReference(centroFormacion.getClass(), centroFormacion.getId());
                curso.setCentroFormacion(centroFormacion);
            }
            Formacion formacion = curso.getFormacion();
            if (formacion != null) {
                formacion = em.getReference(formacion.getClass(), formacion.getId());
                curso.setFormacion(formacion);
            }
            List<Calendariocurso> attachedCalendariocursoList = new ArrayList<Calendariocurso>();
            for (Calendariocurso calendariocursoListCalendariocursoToAttach : curso.getCalendariocursoList()) {
                calendariocursoListCalendariocursoToAttach = em.getReference(calendariocursoListCalendariocursoToAttach.getClass(), calendariocursoListCalendariocursoToAttach.getCalendariocursoPK());
                attachedCalendariocursoList.add(calendariocursoListCalendariocursoToAttach);
            }
            curso.setCalendariocursoList(attachedCalendariocursoList);
            List<Horariocurso> attachedHorariocursoList = new ArrayList<Horariocurso>();
            for (Horariocurso horariocursoListHorariocursoToAttach : curso.getHorariocursoList()) {
                horariocursoListHorariocursoToAttach = em.getReference(horariocursoListHorariocursoToAttach.getClass(), horariocursoListHorariocursoToAttach.getHorariocursoPK());
                attachedHorariocursoList.add(horariocursoListHorariocursoToAttach);
            }
            curso.setHorariocursoList(attachedHorariocursoList);
            em.persist(curso);
            if (centroFormacion != null) {
                centroFormacion.getCursoList().add(curso);
                centroFormacion = em.merge(centroFormacion);
            }
            if (formacion != null) {
                formacion.getCursoList().add(curso);
                formacion = em.merge(formacion);
            }
            for (Calendariocurso calendariocursoListCalendariocurso : curso.getCalendariocursoList()) {
                Curso oldCursoOfCalendariocursoListCalendariocurso = calendariocursoListCalendariocurso.getCurso();
                calendariocursoListCalendariocurso.setCurso(curso);
                calendariocursoListCalendariocurso = em.merge(calendariocursoListCalendariocurso);
                if (oldCursoOfCalendariocursoListCalendariocurso != null) {
                    oldCursoOfCalendariocursoListCalendariocurso.getCalendariocursoList().remove(calendariocursoListCalendariocurso);
                    oldCursoOfCalendariocursoListCalendariocurso = em.merge(oldCursoOfCalendariocursoListCalendariocurso);
                }
            }
            for (Horariocurso horariocursoListHorariocurso : curso.getHorariocursoList()) {
                Curso oldCurso1OfHorariocursoListHorariocurso = horariocursoListHorariocurso.getCurso1();
                horariocursoListHorariocurso.setCurso1(curso);
                horariocursoListHorariocurso = em.merge(horariocursoListHorariocurso);
                if (oldCurso1OfHorariocursoListHorariocurso != null) {
                    oldCurso1OfHorariocursoListHorariocurso.getHorariocursoList().remove(horariocursoListHorariocurso);
                    oldCurso1OfHorariocursoListHorariocurso = em.merge(oldCurso1OfHorariocursoListHorariocurso);
                }
            }
            
        } catch (Exception ex) {
            if (findCurso(curso.getId()) != null) {
                throw new PreexistingEntityException("Curso " + curso + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Curso curso) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Curso persistentCurso = em.find(Curso.class, curso.getId());
            Centroformacion centroFormacionOld = persistentCurso.getCentroFormacion();
            Centroformacion centroFormacionNew = curso.getCentroFormacion();
            Formacion formacionOld = persistentCurso.getFormacion();
            Formacion formacionNew = curso.getFormacion();
            List<Calendariocurso> calendariocursoListOld = persistentCurso.getCalendariocursoList();
            List<Calendariocurso> calendariocursoListNew = curso.getCalendariocursoList();
            List<Horariocurso> horariocursoListOld = persistentCurso.getHorariocursoList();
            List<Horariocurso> horariocursoListNew = curso.getHorariocursoList();
            List<String> illegalOrphanMessages = null;
            for (Calendariocurso calendariocursoListOldCalendariocurso : calendariocursoListOld) {
                if (!calendariocursoListNew.contains(calendariocursoListOldCalendariocurso)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Calendariocurso " + calendariocursoListOldCalendariocurso + " since its curso field is not nullable.");
                }
            }
            for (Horariocurso horariocursoListOldHorariocurso : horariocursoListOld) {
                if (!horariocursoListNew.contains(horariocursoListOldHorariocurso)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Horariocurso " + horariocursoListOldHorariocurso + " since its curso1 field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (centroFormacionNew != null) {
                centroFormacionNew = em.getReference(centroFormacionNew.getClass(), centroFormacionNew.getId());
                curso.setCentroFormacion(centroFormacionNew);
            }
            if (formacionNew != null) {
                formacionNew = em.getReference(formacionNew.getClass(), formacionNew.getId());
                curso.setFormacion(formacionNew);
            }
            List<Calendariocurso> attachedCalendariocursoListNew = new ArrayList<Calendariocurso>();
            for (Calendariocurso calendariocursoListNewCalendariocursoToAttach : calendariocursoListNew) {
                calendariocursoListNewCalendariocursoToAttach = em.getReference(calendariocursoListNewCalendariocursoToAttach.getClass(), calendariocursoListNewCalendariocursoToAttach.getCalendariocursoPK());
                attachedCalendariocursoListNew.add(calendariocursoListNewCalendariocursoToAttach);
            }
            calendariocursoListNew = attachedCalendariocursoListNew;
            curso.setCalendariocursoList(calendariocursoListNew);
            List<Horariocurso> attachedHorariocursoListNew = new ArrayList<Horariocurso>();
            for (Horariocurso horariocursoListNewHorariocursoToAttach : horariocursoListNew) {
                horariocursoListNewHorariocursoToAttach = em.getReference(horariocursoListNewHorariocursoToAttach.getClass(), horariocursoListNewHorariocursoToAttach.getHorariocursoPK());
                attachedHorariocursoListNew.add(horariocursoListNewHorariocursoToAttach);
            }
            horariocursoListNew = attachedHorariocursoListNew;
            curso.setHorariocursoList(horariocursoListNew);
            curso = em.merge(curso);
            if (centroFormacionOld != null && !centroFormacionOld.equals(centroFormacionNew)) {
                centroFormacionOld.getCursoList().remove(curso);
                centroFormacionOld = em.merge(centroFormacionOld);
            }
            if (centroFormacionNew != null && !centroFormacionNew.equals(centroFormacionOld)) {
                centroFormacionNew.getCursoList().add(curso);
                centroFormacionNew = em.merge(centroFormacionNew);
            }
            if (formacionOld != null && !formacionOld.equals(formacionNew)) {
                formacionOld.getCursoList().remove(curso);
                formacionOld = em.merge(formacionOld);
            }
            if (formacionNew != null && !formacionNew.equals(formacionOld)) {
                formacionNew.getCursoList().add(curso);
                formacionNew = em.merge(formacionNew);
            }
            for (Calendariocurso calendariocursoListNewCalendariocurso : calendariocursoListNew) {
                if (!calendariocursoListOld.contains(calendariocursoListNewCalendariocurso)) {
                    Curso oldCursoOfCalendariocursoListNewCalendariocurso = calendariocursoListNewCalendariocurso.getCurso();
                    calendariocursoListNewCalendariocurso.setCurso(curso);
                    calendariocursoListNewCalendariocurso = em.merge(calendariocursoListNewCalendariocurso);
                    if (oldCursoOfCalendariocursoListNewCalendariocurso != null && !oldCursoOfCalendariocursoListNewCalendariocurso.equals(curso)) {
                        oldCursoOfCalendariocursoListNewCalendariocurso.getCalendariocursoList().remove(calendariocursoListNewCalendariocurso);
                        oldCursoOfCalendariocursoListNewCalendariocurso = em.merge(oldCursoOfCalendariocursoListNewCalendariocurso);
                    }
                }
            }
            for (Horariocurso horariocursoListNewHorariocurso : horariocursoListNew) {
                if (!horariocursoListOld.contains(horariocursoListNewHorariocurso)) {
                    Curso oldCurso1OfHorariocursoListNewHorariocurso = horariocursoListNewHorariocurso.getCurso1();
                    horariocursoListNewHorariocurso.setCurso1(curso);
                    horariocursoListNewHorariocurso = em.merge(horariocursoListNewHorariocurso);
                    if (oldCurso1OfHorariocursoListNewHorariocurso != null && !oldCurso1OfHorariocursoListNewHorariocurso.equals(curso)) {
                        oldCurso1OfHorariocursoListNewHorariocurso.getHorariocursoList().remove(horariocursoListNewHorariocurso);
                        oldCurso1OfHorariocursoListNewHorariocurso = em.merge(oldCurso1OfHorariocursoListNewHorariocurso);
                    }
                }
            }
            
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = curso.getId();
                if (findCurso(id) == null) {
                    throw new NonexistentEntityException("The curso with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Curso curso;
            try {
                curso = em.getReference(Curso.class, id);
                curso.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The curso with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Calendariocurso> calendariocursoListOrphanCheck = curso.getCalendariocursoList();
            for (Calendariocurso calendariocursoListOrphanCheckCalendariocurso : calendariocursoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Curso (" + curso + ") cannot be destroyed since the Calendariocurso " + calendariocursoListOrphanCheckCalendariocurso + " in its calendariocursoList field has a non-nullable curso field.");
            }
            List<Horariocurso> horariocursoListOrphanCheck = curso.getHorariocursoList();
            for (Horariocurso horariocursoListOrphanCheckHorariocurso : horariocursoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Curso (" + curso + ") cannot be destroyed since the Horariocurso " + horariocursoListOrphanCheckHorariocurso + " in its horariocursoList field has a non-nullable curso1 field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Centroformacion centroFormacion = curso.getCentroFormacion();
            if (centroFormacion != null) {
                centroFormacion.getCursoList().remove(curso);
                centroFormacion = em.merge(centroFormacion);
            }
            Formacion formacion = curso.getFormacion();
            if (formacion != null) {
                formacion.getCursoList().remove(curso);
                formacion = em.merge(formacion);
            }
            em.remove(curso);
            
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Curso> findCursoEntities() {
        return findCursoEntities(true, -1, -1);
    }

    public List<Curso> findCursoEntities(int maxResults, int firstResult) {
        return findCursoEntities(false, maxResults, firstResult);
    }

    private List<Curso> findCursoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Curso.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Curso findCurso(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Curso.class, id);
        } finally {
            em.close();
        }
    }

    public int getCursoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Curso> rt = cq.from(Curso.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
